package gui;

import geodata.BuildingData;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.BoxLayout;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

import record.ProjectRecord;
import request.RequestFactory;
import request.RequestType;
import request.SaveRequest;
import system.Client;

/**
 * A windows that will get information about the building requirements.
 * @author Stephan
 *
 */
@SuppressWarnings("serial")
public class BuildingRequirementsWindow extends JPanel implements
		ActionListener
{	
	/**
	 * A text field for the user to enter the cooling block load.
	 */
	private JTextField coolingBlockLoad;
	/**
	 * A text field for the user to enter the heating block load.
	 */
	private JTextField heatingBlockLoad;
	/**
	 * A text field for the user to enter the net average heat transfer.
	 */
	private JTextField netAverageHeatTransfer;
	/**
	 * A text field for the user to enter the heat pump inlet.
	 */
	private JTextField heatPumpInlet;
	/**
	 * A text field for the user to enter the heat pump outlet.
	 */
	private JTextField heatPumpOutlet;
	/**
	 * A text field for the user to enter the power input cooling.
	 */
	private JTextField powerInputCooling;
	/**
	 * A text field for the user to enter the power input heating.
	 */
	private JTextField powerInputHeating;
	/**
	 * A button that will print the graph.
	 */
	private JButton printGraph;
	/**
	 * A button that will commit any new data.
	 */
	private JButton doneButton;
	/**
	 * A line graph.
	 */
//	private GraphPanel graph;
	/**
	 * A table from which the graph will be created.
	 */
	private JTable energyTable;
	/**
	 * The client through which this window will communicate with the server.
	 */
	@SuppressWarnings("unused")
	private Client client;
	/**
	 * The currently active project record.
	 */
	private ProjectRecord record;
	/**
	 * The application which is displaying this window.
	 */
	private Application app;
	
	private RequestFactory factory = new RequestFactory();
	
	/**
	 * Creates this window and adds it to the given application
	 * @param record the currently active project record
	 * @param pApp the application which this window will be displayed in
	 */
	public BuildingRequirementsWindow(ProjectRecord record, Application pApp)
	{
		this.client = pApp.getClient();
		this.record = record;
		
		Container pane = this;
		
		coolingBlockLoad = new JTextField();
		heatingBlockLoad = new JTextField();
		netAverageHeatTransfer = new JTextField();
		heatPumpInlet = new JTextField();
		heatPumpOutlet = new JTextField();
		powerInputCooling = new JTextField();
		powerInputHeating = new JTextField();
				
		coolingBlockLoad.setInputVerifier(new DoubleVerifier());
		heatingBlockLoad.setInputVerifier(new DoubleVerifier());
		netAverageHeatTransfer.setInputVerifier(new DoubleVerifier());
		heatPumpInlet.setInputVerifier(new DoubleVerifier());
		heatPumpOutlet.setInputVerifier(new DoubleVerifier());
		powerInputCooling.setInputVerifier(new DoubleVerifier());
		powerInputHeating.setInputVerifier(new DoubleVerifier());
		
		printGraph = new JButton("Print Graph");
		doneButton = new JButton("Done");
		
		printGraph.addActionListener(this);
		doneButton.addActionListener(this);
		
//		graph = new GraphPanel();		
//		
//		energyTable = new JTable(new EnergyTableModel());
//		energyTable.setFillsViewportHeight(true);
		
		JPanel coolingBlockLoadPanel = new JPanel(new BorderLayout());
		JPanel heatingBlockLoadPanel = new JPanel(new BorderLayout());
		JPanel netAverageHeatTransferPanel = new JPanel(new BorderLayout());
		JPanel heatPumpInletPanel = new JPanel(new BorderLayout());
		JPanel heatPumpOutletPanel = new JPanel(new BorderLayout());
		JPanel powerInputCoolingPanel = new JPanel(new BorderLayout());
		JPanel powerInputHeatingPanel = new JPanel(new BorderLayout());
		
		coolingBlockLoadPanel.add(new JLabel("Cooling Block Load"), BorderLayout.LINE_START);
		coolingBlockLoadPanel.add(coolingBlockLoad, BorderLayout.CENTER);
		
		heatingBlockLoadPanel.add(new JLabel("Heating Block Load"), BorderLayout.LINE_START);
		heatingBlockLoadPanel.add(heatingBlockLoad, BorderLayout.CENTER);
		
		netAverageHeatTransferPanel.add(new JLabel("Net average Heat Transfer"), BorderLayout.LINE_START);
		netAverageHeatTransferPanel.add(netAverageHeatTransfer, BorderLayout.CENTER);
		
		heatPumpInletPanel.add(new JLabel("Heat Pump Inlet"), BorderLayout.LINE_START);
		heatPumpInletPanel.add(heatPumpInlet, BorderLayout.CENTER);
		
		heatPumpOutletPanel.add(new JLabel("Heat Pump Outlet"), BorderLayout.LINE_START);
		heatPumpOutletPanel.add(heatPumpOutlet, BorderLayout.CENTER);
		
		powerInputCoolingPanel.add(new JLabel("Power Input Cooling"), BorderLayout.LINE_START);
		powerInputCoolingPanel.add(powerInputCooling, BorderLayout.CENTER);
		
		powerInputHeatingPanel.add(new JLabel("Power Input Heating"), BorderLayout.LINE_START);
		powerInputHeatingPanel.add(powerInputHeating, BorderLayout.CENTER);
		
		JPanel graphPanel = new JPanel();
		graphPanel.setLayout(new BoxLayout(graphPanel, BoxLayout.Y_AXIS));
//		graphPanel.add(graph);
		
		JScrollPane tableScroller = new JScrollPane(energyTable);
		tableScroller.setMinimumSize(new Dimension(300, 300));
		
//		JSplitPane tableGraph = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tableScroller, graph);
//		tableGraph.setResizeWeight(.5);
		
		pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
		
		JPanel inputPanel = new JPanel();
		inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.Y_AXIS));
				
		JPanel buttonPanel = new JPanel();
		buttonPanel.setAlignmentX(LEFT_ALIGNMENT);
		//buttonPanel.add(printGraph);
		buttonPanel.add(doneButton);
	
		inputPanel.add(buttonPanel);
		inputPanel.add(coolingBlockLoadPanel);
		inputPanel.add(heatingBlockLoadPanel);
		inputPanel.add(netAverageHeatTransferPanel);
		inputPanel.add(heatPumpInletPanel);
		inputPanel.add(heatPumpOutletPanel);
		inputPanel.add(powerInputCoolingPanel);
		inputPanel.add(powerInputHeatingPanel);
		
		pane.add(inputPanel);
		//pane.add(tableGraph);
		
		initFields();
		
		app = pApp;
		app.getContentPane().removeAll();
		app.getContentPane().add(this);
		app.setVisible(true);
	}
	
	
	
	/**
	 * Populates the data for the text fields of this window.
	 */
	private void initFields()
	{
		BuildingData data = record.getBuildingData();
		
		coolingBlockLoad.setText("" + data.getFieldByName("Cooling Block Load").getValue().toString());
		heatingBlockLoad.setText("" + data.getFieldByName("Heating Block Load").getValue().toString());
		netAverageHeatTransfer.setText("" + data.getFieldByName("Net Average Heat Transfer").getValue().toString());
		heatPumpInlet.setText("" + data.getFieldByName("Heat Pump Inlet").getValue().toString());
		heatPumpOutlet.setText("" + data.getFieldByName("Heat Pump Outlet").getValue().toString());
		powerInputCooling.setText("" + data.getFieldByName("Power Input Cooling").getValue().toString());
		powerInputHeating.setText("" + data.getFieldByName("Power Input Heating").getValue().toString());
		
	}

	/**
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent e)
	{
		if(e.getSource().equals(doneButton))
		{
			storeData();
			SaveRequest save = (SaveRequest)factory.getRequest(RequestType.Save);
			save.setRecord(record);
			try {
				record.setBuildingRequirementsComplete(true);
				app.getClient().sendRequest(save);
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (ClassNotFoundException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			new ProjectMenuWindow(record, app);
		}
		else if(e.getSource().equals(printGraph))
		{
			// TODO: Print Graph
		}
	}



	/**
	 * Stores the data in the window into the current project record
	 */
	private void storeData()
	{
		BuildingData data = record.getBuildingData();
		
		data.getFieldByName("Cooling Block Load").setValue(Double.parseDouble(coolingBlockLoad.getText()));
		data.getFieldByName("Heating Block Load").setValue(Double.parseDouble(heatingBlockLoad.getText()));
		data.getFieldByName("Heat Pump Inlet").setValue(Double.parseDouble(heatPumpInlet.getText()));
		data.getFieldByName("Heat Pump Outlet").setValue(Double.parseDouble(heatPumpOutlet.getText()));
		data.getFieldByName("Net Average Heat Transfer").setValue(Double.parseDouble(netAverageHeatTransfer.getText()));
		data.getFieldByName("Power Input Cooling").setValue(Double.parseDouble(powerInputCooling.getText()));
		data.getFieldByName("Power Input Heating").setValue(Double.parseDouble(powerInputHeating.getText()));
	}
	
	/**
	 * Input verifier that will guarantee that the user has entered only 
	 * valid data
	 * @author Stephan
	 *
	 */
	class DoubleVerifier extends InputVerifier
	{
		// Return true if there is a valid double that is greater than or equal to 0
		/**
		 * @see javax.swing.InputVerifier#verify(javax.swing.JComponent)
		 */
		@Override
		public boolean verify(JComponent input)
		{
			if(((JTextField)input).getText().equals(""))
				return true;
			try
			{
				double d = Double.parseDouble(((JTextField)input).getText());
				return d >= 0;
			}
			catch(NumberFormatException e)
			{
				return false;
			}
		}
		
		/**
		 * @see javax.swing.InputVerifier#shouldYieldFocus(javax.swing.JComponent)
		 */
		// Provides a visual indication that the user has f*ed up
		@Override
		public boolean shouldYieldFocus(JComponent input)
		{
			boolean retval = super.shouldYieldFocus(input);
			
			if(retval)
				input.setBackground(Color.WHITE);
			else
				input.setBackground(Color.YELLOW);
			
			return retval;
		}
	} // End inner class

}
